<template>
  <el-form ref="formRef" :model="modelValue" :rules="rules">
    <el-form-item
      v-for="item in getFormItems(formItems)"
      :label="item.label"
      :key="item.key"
      :prop="item.key"
      style="margin-right: 0"
    >
      <slot :name="item.key">
        <component :is="getComponent(item)" v-model="modelValue[item.key]" style="width: 224px" v-bind="getProps(item)">
          <template v-if="item.type === 'select'">
            <el-option
              v-for="option in getProps(item).options || []"
              :key="option.value || option.id"
              :label="option.label || option.name"
              :value="option.value || option.id"
            ></el-option>
          </template>
        </component>
      </slot>
    </el-form-item>
    <!-- 操作按钮区域插槽 -->
    <el-form-item style="margin-left: 20px">
      <slot name="actions"></slot>
    </el-form-item>
  </el-form>
</template>

<script setup>
import {
  ElInput,
  ElInputNumber,
  ElSelect,
  ElRadioGroup,
  ElCheckboxGroup,
  ElTimePicker,
  ElDatePicker,
  ElSwitch,
  ElOption
} from 'element-plus'
import { h, useTemplateRef } from 'vue'
defineProps(['formItems', 'rules'])
const modelValue = defineModel()
const formInstance = useTemplateRef('formRef')
const componentMap = {
  input: ElInput,
  number: ElInputNumber,
  select: ElSelect,
  radio: ElRadioGroup,
  checkbox: ElCheckboxGroup,
  date: ElDatePicker,
  time: ElTimePicker,
  switch: ElSwitch
}

function getFormItems(formItems) {
  if (formItems.length === 0) {
    return []
  }
  return formItems.filter(i => i.showItem !== false)
}

function getComponent(item) {
  const { type } = item
  if (typeof type !== 'string') {
    return type
  }
  return componentMap[type]
}

const rootProps = ['label', 'key', 'type']
function omit(obj, keys) {
  const result = { ...obj }
  ;(Array.isArray(keys) ? keys : [keys]).forEach(key => {
    delete result[key]
  })
  return result
}
function getProps(item) {
  if (item.props) return item.props
  return omit(item, rootProps)
}

defineExpose({
  validate(...args) {
    return formInstance.value.validate(...args)
  }, // 新增方法
  validateField: (props, callback) => formInstance.value.validateField(props, callback),

  resetFields: () => formInstance.value.resetFields(),

  clearValidate: props => formInstance.value.clearValidate(props)
})
</script>

<style scoped>
</style>
